package store.lunangangster.nodeflow.rt.element;

import store.lunangangster.nodeflow.core.component.NodeComponent;
import store.lunangangster.nodeflow.enums.NodeType;
import store.lunangangster.nodeflow.exception.ExecuteException;
import store.lunangangster.nodeflow.rt.Slot;

/**
 * 节点的可执行类
 *
 * @author cwk
 * @version 1.0
 */
public class Node implements Executable, Identifiable<String> {

	private String id;

	private String className;

	private Class<?> clazz;

	private NodeType type;

	private NodeComponent nodeComponent;

	/**
	 * Node的执行方法，所有的Executable对象的执行操作都会到这个方法上来。
	 * 一个Node的执行逻辑，实际上是其对应的{@link NodeComponent#process()}的执行逻辑
	 * @param slotIndex	被分配的{@link Slot}下标
	 */
	@Override
	public void execute(Integer slotIndex) {
		if (clazz == null || type == null) {
			throw new ExecuteException("Node's message is not complete, can not to execute");
		}
		if (nodeComponent == null) {
			throw new ExecuteException("Node's nodeComponent cannot be null");
		}
		try {
			// 设置执行槽
			nodeComponent.setSlot(slotIndex);
			// 执行
			nodeComponent.process();
		} finally {
			// 清除执行槽
			nodeComponent.removeSlotTl();
		}
	}

	public Node() {
	}

	/**
	 * 判断Node是否是某个NodeComponent类型的执行节点
	 * @param clazz	NodeComponent子类Class对象
	 * @return	如果是则返回true
	 */
	public boolean isComponent(Class<? extends NodeComponent> clazz) {
		if (clazz == null || this.clazz == null) {
			return false;
		}
		return clazz.isAssignableFrom(this.clazz);
	}

	/**
	 * 获取当前对象的id
	 * @return  id
	 */
	@Override
	public String getId() {
		return id;
	}

	/**
	 * 设置当前对象的id
	 * @param id	chainId
	 */
	public Node setId(String id) {
		this.id = id;
		return this;
	}

	/**
	 * 获取当前Node对应的NodeComponent的Class对象
	 * @return 当前Node对应的NodeComponent的Class对象
	 */
	public Class<?> getClazz() {
		return clazz;
	}

	/**
	 * 设置当前Node对应的NodeComponent的Class对象
	 */
	public void setClazz(
			Class<?> clazz) {
		this.clazz = clazz;
	}

	/**
	 * 获取当前Node对应的{@link NodeType}类型
	 * @return	Node对应的NodeType
	 */
	public NodeType getType() {
		return type;
	}

	/**
	 * 设置当前Node对应的{@link NodeType}类型
	 * @param type	nodeType
	 */
	public void setType(NodeType type) {
		this.type = type;
	}

	/**
	 * 获取当前Node对应NodeComponent的className
	 * @return	NodeComponent对应的className
	 */
	public String getClassName() {
		return className;
	}

	/**
	 * 设置当前Node对应的NodeComponent的className
	 * @param className	className for NodeComponent
	 */
	public void setClassName(String className) {
		this.className = className;
	}

	/**
	 * 获取当前Node对应的NodeComponent对象
	 * @return NodeComponent对象
	 */
	public NodeComponent getNodeComponent() {
		return nodeComponent;
	}

	/**
	 * 设置当前Node对应的NodeComponent对象
	 * @param nodeComponent	NodeComponent对象
	 */
	public void setNodeComponent(NodeComponent nodeComponent) {
		this.nodeComponent = nodeComponent;
	}
}
